package com.wxy.ej.flow.modules.taskflow.service.nodeExecuteStrategy;

import com.alibaba.fastjson.JSONObject;
import com.rt.easyjava.common.base.Result;
import com.rt.easyjava.common.utils.others.DateUtils;
import com.wxy.ej.flow.modules.taskflow.dto.DataDto;
import com.wxy.ej.flow.modules.taskflow.dto.NodeDto;
import lombok.extern.slf4j.Slf4j;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

@Slf4j
public abstract class NodeStrategy {

    // 当前node在循环里，遇到break，continue了， 就不执行
    public boolean isSkipCurrentNode(DataDto dataDto) {
        if (dataDto.isInCircle()) {
            if (dataDto.isBreak()) {
                return true;
            }
            if (dataDto.isContinue()) {
                return true;
            }
        }
        return false;
    }

    public Object executeScriptForResult(DataDto dataDto, String script) throws ScriptException {
        log.info(script);
        ScriptEngineManager factory = new ScriptEngineManager();
        ScriptEngine engine = factory.getEngineByName("javascript");
        Iterator it = dataDto.getStorageDataVarMap().keySet().iterator();
        while (it.hasNext()) {
            String key = (String)it.next();
            Object data = dataDto.getStorageDataVarMap().get(key);
            engine.put(key, data);
        }
        engine.eval("var a = "+script);
        Object o = engine.get("a");
        return o;
    }

    public void executeScripts(DataDto dataDto, String script) throws ScriptException {
        ScriptEngineManager factory = new ScriptEngineManager();
        //ScriptEngine engine = factory.getEngineByName("nashorn");
        ScriptEngine engine = factory.getEngineByName("javascript");
        Iterator it = dataDto.getStorageDataVarMap().keySet().iterator();
        while (it.hasNext()) {
            String key = (String)it.next();
            Object data = dataDto.getStorageDataVarMap().get(key);
            engine.put(key, data);
        }
        engine.eval(script);
    }

    private String[] mustExecuteNodeArr = {"controller-circle-start-node"};

    public Result templateAction(NodeDto node, JSONObject flowDataJson, DataDto dataDto) {
        try {
            if (!"link".equalsIgnoreCase(node.getType())) {
                dataDto.getLogList().add(DateUtils.currentDate(">HH:mm:ss.SSS") + ": '" + node.getName() + "' 执行");
            }
            List<String> mustExecuteNodeList = Arrays.asList(mustExecuteNodeArr);
            if (isSkipCurrentNode(dataDto) && !mustExecuteNodeList.contains(node.getType())) {
                log.info(node.getName() + ": 跳过...");
                if (!"link".equalsIgnoreCase(node.getType())) {
                    dataDto.getLogList().add("跳过执行");
                }
                return Result.builder();
            }
            return action(node, flowDataJson, dataDto);
        }catch (Exception e) {
            e.printStackTrace();
            dataDto.getLogList().add(e.getLocalizedMessage());
            return Result.builder().fault();
        }
    }


    public abstract Result action(NodeDto node, JSONObject flowDataJson, DataDto dataDto) throws Exception;


}
